//#include <fstream>
//#include <iostream>
//
//#include "../Core/Databank.hpp"
//#include "../Core/Game.hpp"
//#include "../Core/Log.hpp"
//#include "../Objects/Player.hpp"
//
//#include "Dungeon.hpp"
//
//Dungeon::~Dungeon()
//{
//	TileData.clear();
//	delete ViewMap;
//}
//
//void Dungeon::generate(std::string name, unsigned int numFloors, unsigned int width, unsigned int height, EGenerationAlgo algo)
//{
//	Name = name;
//	TileData.resize(width, std::vector<Tile*>(height, NULL));
//	ViewMap = new TCODMap(width, height);
//
//	for (unsigned int x = 0; x < width; ++x)
//		for (unsigned int y = 0; y < height; ++y)
//			TileData[x][y] = new Tile(ETT_NONE, "wall", '#', Vector2d(x, y), this, false, false);
//
//	switch (algo)
//	{
//	case EGA_CELLULARAUTOMATA:
//		GenerateCellularAutomata(10, 50);
//		break;
//
//	case EGA_BSP:
//		GenerateBsp(4, 8);
//		break;
//
//	default:
//		Log::write("Invalid generation algorithm.");
//		exit(1);
//		break;
//	}
//
//	for (unsigned int i = 0; i < 30; ++i)
//	{
//		Game::Actors.push_back(new Actor("Kobold", Databank::getRaceByName("Kobold")));
//		Game::Actors.back()->setZone(this);
//		
//		int x = TCODRandom::getInstance()->getInt(1, 99);
//		int y = TCODRandom::getInstance()->getInt(1, 99);
//		while (true) 
//		{
//			if (TileData[x][y]->isPassable()) 
//			{
//				Game::Actors.back()->setPosition(Vector2d(x, y));
//				break;
//			}
//
//			x = TCODRandom::getInstance()->getInt(1, 99);
//			y = TCODRandom::getInstance()->getInt(1, 99);
//		}
//	}
//
//	while (true)
//	{
//		int x = TCODRandom::getInstance()->getInt(1, 99);
//		int y = TCODRandom::getInstance()->getInt(1, 99);
//		if (TileData[x][y]->isPassable())
//		{
//			gPlayer->setPosition(Vector2d(x, y));
//			break;
//		}
//	}
//
//	gPlayer->setZone(this);
//
//	saveToFile("dungeon");
//}
//
//void Dungeon::saveToFile(std::string fileName)
//{
//	std::ofstream file((std::string("data/dungeons/")+fileName).c_str());
//	for (unsigned int x = 0; x < TileData.size(); ++x)
//	{
//		for (unsigned int y = 0; y < TileData[x].size(); ++y)
//			file << TileData[y][x]->getShape();
//		file << std::endl;
//	}
//	file.close();
//}
//
//bool Dungeon::visitNode(TCODBsp* node, void* userData)
//{
//	if (node->isLeaf())
//	{
//		int xmin = node->x;
//		int xmax = node->x+node->w-1;
//		int ymin = node->y;
//		int ymax = node->y+node->h-1;
//
//		if (xmin == 0) ++xmin;
//		if (ymin == 0) ++ymin;
//
//		if (xmax == TileData.size()) --xmax;
//		if (ymax == TileData[0].size()) --ymax;
//
//		xmin = TCODRandom::getInstance()->getInt(xmin, xmax-5);
//		ymin = TCODRandom::getInstance()->getInt(ymin, ymax-5);
//		xmax = TCODRandom::getInstance()->getInt(xmin+5, xmax);
//		ymax = TCODRandom::getInstance()->getInt(ymin+5, ymax);
//
//		node->x = xmin;
//		node->y = ymin;
//		node->w = xmax-xmin+1;
//		node->h = ymax-ymin+1;
//
//		for (int x = xmin; x < xmax; ++x)
//			for (int y = ymin; y < ymax; ++y)
//			{
//				delete TileData[x][y];
//				TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//			}
//	}
//	else
//	{
//		TCODBsp* left = node->getLeft();
//		TCODBsp* right = node->getRight();
//
//		node->x = MIN(left->x, right->x);
//		node->y = MIN(left->y, right->y);
//		node->w= MAX(left->x+left->w, right->x+right->w) - node->x;
//		node->h= MAX(left->y+left->h, right->y+right->h) - node->y;
//
//		if (node->horizontal)
//		{
//			if (left->x+left->w-1 < right->x || right->x+right->w-1 < left->x)
//			{
//				int x1 = TCODRandom::getInstance()->getInt(left->x, left->x+left->w-1);
//				int x2 = TCODRandom::getInstance()->getInt(right->x, right->x+right->w-1);
//				int y = TCODRandom::getInstance()->getInt(left->y+left->h, right->y);
//
//				VerticalLineUp(x1, y-1);
//				HorizontalLine(x1, x2, y);
//				VerticalLineDown(x2, y+1);
//			}
//			else
//			{
//				int xmin = MAX(left->x, right->x);
//				int xmax = MIN(left->x+left->w-1, right->x+right->w-1);
//				int x = TCODRandom::getInstance()->getInt(xmin, xmax);
//				VerticalLineDown(x, right->y);
//				VerticalLineUp(x, right->y-1);
//			}
//		}
//		else
//		{
//			if (left->y+left->h-1 < right->y || right->y+right->h-1 < left->y)
//			{
//				int y1 = TCODRandom::getInstance()->getInt(left->y, left->y+left->h-1);
//				int y2 = TCODRandom::getInstance()->getInt(right->y, right->y+right->h-1);
//				int x = TCODRandom::getInstance()->getInt(left->x+left->w, right->x);
//				HorizontalLineLeft(x-1, y1);
//				VerticalLine(x, y1, y2);
//				HorizontalLineRight(x+1, y2);
//			}
//			else
//			{
//				int ymin = MAX(left->y, right->y);
//				int ymax = MIN(left->y+left->h-1, right->y+right->h-1);
//				int y = TCODRandom::getInstance()->getInt(ymin, ymax);
//				HorizontalLineLeft(right->x-1, y);
//				HorizontalLineRight(right->x, y);
//			}
//		}
//	}
//
//	return true;
//}
//
//void Dungeon::GenerateBsp(int roomsize, int subdivs)
//{
//	BSP = new TCODBsp(0, 0, TileData.size(), TileData[0].size());
//	BSP->splitRecursive(NULL, subdivs, roomsize+1, roomsize+1, 1.5f, 1.5f);
//	BSP->traverseInvertedLevelOrder(this, NULL);
//	delete BSP;
//}
//
//void Dungeon::GenerateCellularAutomata(unsigned int iterations, unsigned int percentWalls)
//{
//	for (unsigned int x = 1; x < TileData.size()-1; ++x)
//		for (unsigned int y = 1; y < TileData[x].size()-1; ++y)
//		{
//			unsigned int rnd = TCODRandom::getInstance()->getInt(1, 100);
//			if (rnd > percentWalls)
//			{
//				delete TileData[x][y];
//				TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//			}
//		}
//
//	for (unsigned int i = 0; i < iterations; ++i)
//		for (unsigned int x = 0; x < TileData.size(); ++x)
//			for (unsigned int y = 0; y < TileData[x].size(); ++y)
//				if (x == 0 || x == TileData.size()-1 || y == 0 || y == TileData[x].size()-1)
//				{
//					delete TileData[x][y];
//					TileData[x][y] = new Tile(ETT_NONE, "wall", '#', Vector2d(x, y), this, false, false);
//				}
//				else
//				{
//					unsigned int w = 0;
//					if (TileData[x-1][y-1]->getName() == "wall")
//						w++;
//					if (TileData[x-1][y]->getName() == "wall")
//						w++;
//					if (TileData[x-1][y+1]->getName() == "wall")
//						w++;
//					if (TileData[x][y-1]->getName() == "wall")
//						w++;
//					if (TileData[x][y]->getName() == "wall")
//						w++;
//					if (TileData[x][y+1]->getName() == "wall")
//						w++;
//					if (TileData[x+1][y-1]->getName() == "wall")
//						w++;
//					if (TileData[x+1][y]->getName() == "wall")
//						w++;
//					if (TileData[x+1][y+1]->getName() == "wall")
//						w++;
//
//					if (w > 4)
//					{
//						delete TileData[x][y];
//						TileData[x][y] = new Tile(ETT_NONE, "wall", '#', Vector2d(x, y), this, false, false);
//					}
//					else
//					{	
//						delete TileData[x][y];
//						TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//					}
//				}
//
//	bool ffound = false;
//	bool found = false;
//	unsigned int fpos;
//	unsigned int pos;
//
//	for (unsigned int y = 1; y < TileData[0].size()-2; ++y)	
//	{
//		for (unsigned int x = 1; x < TileData.size()-2; ++x)
//		{
//			if (TileData[x][y]->getName() == "floor")
//			{
//				if (TileData[x+1][y]->getName() == "floor")
//				{
//					fpos = x;
//					ffound = true;
//				}
//				else if (TileData[x+1][y]->getName() == "wall")
//				{
//					pos = x+1;
//					found = true;
//				}
//			}
//			else if (ffound && found && TileData[x][y]->getName() == "wall" && TileData[x+1][y]->getName() == "floor")
//			{
//				ffound = false;
//				found = false;
//
//				if (pos - fpos < 5)
//				{
//					for (unsigned int i = pos; i < x+1; ++i)
//					{
//						if (TileData[i][y-1]->getName() == "floor")
//							break;
//						if (TileData[i][y+1]->getName() == "floor")
//							break;
//
//						delete TileData[x][y];
//						TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//					}
//				}
//			}
//		}
//	}
//}
//
//void Dungeon::HorizontalLine(int x1, int x2, int y)
//{
//	int x = x1;
//	int dx = (x1 > x2 ? -1 : 1);
//	
//	delete TileData[x][y];
//	TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//	
//	if (x1 == x2) return;
//	
//	while (x != x2)
//	{
//		x += dx;
//		delete TileData[x][y];
//		TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//	}
//}
//
//void Dungeon::HorizontalLineLeft(int x, int y)
//{
//	while (x > 0 && TileData[x][y]->getName() != "floor") 
//	{
//		delete TileData[x][y];
//		TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//		x--;
//	}
//}
//
//void Dungeon::HorizontalLineRight(int x, int y)
//{
//	while (x < (signed)TileData.size()-1 && TileData[x][y]->getName() != "floor") 
//	{
//		delete TileData[x][y];
//		TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//		x++;
//	}
//}
//
//void Dungeon::VerticalLine(int x, int y1, int y2)
//{
//	int y = y1;
//	int dy = (y1 > y2 ? -1 : 1);
//
//	delete TileData[x][y];
//	TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//
//	if (y1 == y2) return;
//
//	while (y != y2)
//	{
//		y += dy;
//		delete TileData[x][y];
//		TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//	}
//}
//
//void Dungeon::VerticalLineUp(int x, int y)
//{
//	while (y > 0 && TileData[x][y]->getName() != "floor") 
//	{
//		delete TileData[x][y];
//		TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//		y--;
//	}
//}
//
//void Dungeon::VerticalLineDown(int x, int y)
//{ 
//	while (y < (signed)TileData[0].size()-1 && TileData[x][y]->getName() != "floor") 
//	{
//		delete TileData[x][y];
//		TileData[x][y] = new Tile(ETT_NONE, "floor", '.', Vector2d(x, y), this, true, true);
//		y++;
//	}
//}
